package com.dbex.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据库连接工具类
 * @author lxx
 *
 */
@SuppressWarnings({"unchecked","rawtypes"})
public class DBUtil {
	private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
	private static String url;
	private static String driver;
	private static String username;
	private static String password;
	static{
		url = MainConfig.getValue("src.url");
		driver = MainConfig.getValue("src.driverClassName");
		username = MainConfig.getValue("src.username");
		password = MainConfig.getValue("src.password");
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException("驱动加载失败！");
		}
	}
	
	public static Connection getConnection(){
		Connection con = tl.get();
		if(con==null)
			try {
				con = DriverManager.getConnection(url, username, password);
				tl.set(con);
			} catch (SQLException e) {
				throw new RuntimeException("获取连接失败", e);
			}
		return con;
	}
	
	public static void closeConnection(){
		Connection con = tl.get();
		if(con!=null)
			try {
				con.close();
				tl.set(null);
			} catch (SQLException e) {
				throw new RuntimeException("关闭连接失败", e);
			}
		
	}
	
	/**
	 * 执行一段DQL语句，返回List
	 * @param sql SQL语句
	 * @return
	 */
	public static List queryList(String sql, Object... params){
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		List list = null;
		try {
			con = getConnection();
			if(StaticConstant.SHOW_SQL) 
				System.out.println("sql:"+sql);
			pstmt = con.prepareStatement(sql);
			if(params != null && params.length > 0){
				for (int i = 0; i < params.length; i++) {
					pstmt.setObject(i+1, params[i]);
				}
			}
			rs = pstmt.executeQuery();
			list = new ArrayList();
			while(rs.next()){
				int num = rs.getMetaData().getColumnCount();
				if(num>1){
					Object[] arr = new Object[num];
					for (int i = 0; i < arr.length; i++) {
						arr[i] = rs.getObject(i+1);
					}
					list.add(arr);
				}else{
					list.add(rs.getObject(1));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {
			if(rs!=null)
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			if(pstmt!=null)
				try {
					pstmt.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			closeConnection();
		}
		return list;
	}
	/**
	 * 执行一段DQL语句，返回List
	 * @param sql SQL语句
	 * @return
	 */
	public static <T> List<T> queryList(String sql, RowMapper<T> rowMapper, Object... params){
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		List list = null;
		try {
			con = getConnection();
			if(StaticConstant.SHOW_SQL) 
				System.out.println("sql:"+sql);
			pstmt = con.prepareStatement(sql);
			if(params != null && params.length > 0){
				for (int i = 0; i < params.length; i++) {
					pstmt.setObject(i+1, params[i]);
				}
			}
			rs = pstmt.executeQuery();
			list = new ArrayList();
			while(rs.next()){
				list.add(rowMapper.rowMapper(rs));
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {
			if(rs!=null)
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			if(pstmt!=null)
				try {
					pstmt.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			closeConnection();
		}
		return list;
	}
	
	
	public static String getUrl() {
		return url;
	}

	public static void main(String[] args) {
		List list = queryList("select table_name from all_tables where owner='YDHL'");
//		List list = queryList("desc YDHL.ydhl_emr");
		System.out.println(list.size());
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i).getClass());
		}
	}

}
